home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / d_edge.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  8KB  |  332 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // d_edge.c
  21.  
  22. #include "quakedef.h"
  23. #include "d_local.h"
  24.  
  25. static int    miplevel;
  26.  
  27. float        scale_for_mip;
  28. /* int            screenwidth; */
  29. int            ubasestep, errorterm, erroradjustup, erroradjustdown;
  30. int            vstartscan;
  31.  
  32. // FIXME: should go away
  33. extern void            R_RotateBmodel (void);
  34. extern void            R_TransformFrustum (void);
  35.  
  36. static vec3_t        transformed_modelorg;
  37.  
  38. /*
  39. ==============
  40. D_DrawPoly
  41.  
  42. ==============
  43. */
  44. void D_DrawPoly (void)
  45. {
  46. // this driver takes spans, not polygons
  47. }
  48.  
  49.  
  50. /*
  51. =============
  52. D_MipLevelForScale
  53. =============
  54. */
  55. int D_MipLevelForScale (float scale)
  56. {
  57.     int        lmiplevel;
  58.  
  59.     if (scale >= d_scalemip[0] )
  60.         lmiplevel = 0;
  61.     else if (scale >= d_scalemip[1] )
  62.         lmiplevel = 1;
  63.     else if (scale >= d_scalemip[2] )
  64.         lmiplevel = 2;
  65.     else
  66.         lmiplevel = 3;
  67.  
  68.     if (lmiplevel < d_minmip)
  69.         lmiplevel = d_minmip;
  70.  
  71.     return lmiplevel;
  72. }
  73.  
  74.  
  75. /*
  76. ==============
  77. D_DrawSolidSurface
  78. ==============
  79. */
  80.  
  81. // FIXME: clean this up
  82.  
  83. void D_DrawSolidSurface (surf_t *surf, int color)
  84. {
  85.     espan_t    *span;
  86.     byte    *pdest;
  87.     int        u, u2, pix;
  88.     
  89.     pix = (color<<24) | (color<<16) | (color<<8) | color;
  90.     for (span=surf->spans ; span ; span=span->pnext)
  91.     {
  92.         pdest = (byte *)d_viewbuffer + screenwidth*span->v;
  93.         u = span->u;
  94.         u2 = span->u + span->count - 1;
  95.         ((byte *)pdest)[u] = pix;
  96.  
  97.         if (u2 - u < 8)
  98.         {
  99.             for (u++ ; u <= u2 ; u++)
  100.                 ((byte *)pdest)[u] = pix;
  101.         }
  102.         else
  103.         {
  104.             for (u++ ; u & 3 ; u++)
  105.                 ((byte *)pdest)[u] = pix;
  106.  
  107.             u2 -= 4;
  108.             for ( ; u <= u2 ; u+=4)
  109.                 *(int *)((byte *)pdest + u) = pix;
  110.             u2 += 4;
  111.             for ( ; u <= u2 ; u++)
  112.                 ((byte *)pdest)[u] = pix;
  113.         }
  114.     }
  115. }
  116.  
  117.  
  118. /*
  119. ==============
  120. D_CalcGradients
  121. ==============
  122. */
  123. void D_CalcGradients (msurface_t *pface)
  124. {
  125.     mplane_t    *pplane;
  126.     float        mipscale;
  127.     vec3_t        p_temp1;
  128.     vec3_t        p_saxis, p_taxis;
  129.     float        t;
  130.  
  131.     pplane = pface->plane;
  132.  
  133.     mipscale = 1.0 / (float)(1 << miplevel);
  134.  
  135.     TransformVector (pface->texinfo->vecs[0], p_saxis);
  136.     TransformVector (pface->texinfo->vecs[1], p_taxis);
  137.  
  138.     t = xscaleinv * mipscale;
  139.     d_sdivzstepu = p_saxis[0] * t;
  140.     d_tdivzstepu = p_taxis[0] * t;
  141.  
  142.     t = yscaleinv * mipscale;
  143.     d_sdivzstepv = -p_saxis[1] * t;
  144.     d_tdivzstepv = -p_taxis[1] * t;
  145.  
  146.     d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
  147.             ycenter * d_sdivzstepv;
  148.     d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
  149.             ycenter * d_tdivzstepv;
  150.  
  151.     VectorScale (transformed_modelorg, mipscale, p_temp1);
  152.  
  153.     t = 0x10000*mipscale;
  154.     sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
  155.             ((pface->texturemins[0] << 16) >> miplevel)
  156.             + pface->texinfo->vecs[0][3]*t;
  157.     tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
  158.             ((pface->texturemins[1] << 16) >> miplevel)
  159.             + pface->texinfo->vecs[1][3]*t;
  160.  
  161. //
  162. // -1 (-epsilon) so we never wander off the edge of the texture
  163. //
  164.     bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
  165.     bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
  166. }
  167.  
  168.  
  169. /*
  170. ==============
  171. D_DrawSurfaces
  172. ==============
  173. */
  174. void D_DrawSurfaces (void)
  175. {
  176.     surf_t            *s;
  177.     msurface_t        *pface;
  178.     surfcache_t        *pcurrentcache;
  179.     vec3_t            world_transformed_modelorg;
  180.     vec3_t            local_modelorg;
  181.  
  182.     currententity = &cl_entities[0];
  183.     TransformVector (modelorg, transformed_modelorg);
  184.     VectorCopy (transformed_modelorg, world_transformed_modelorg);
  185.  
  186. // TODO: could preset a lot of this at mode set time
  187.     if (r_drawflat.value)
  188.     {
  189.         for (s = &surfaces[1] ; s<surface_p ; s++)
  190.         {
  191.             if (!s->spans)
  192.                 continue;
  193.  
  194.             d_zistepu = s->d_zistepu;
  195.             d_zistepv = s->d_zistepv;
  196.             d_ziorigin = s->d_ziorigin;
  197.  
  198.             D_DrawSolidSurface (s, (int)s->data & 0xFF);
  199.             D_DrawZSpans (s->spans);
  200.         }
  201.     }
  202.     else
  203.     {
  204.         for (s = &surfaces[1] ; s<surface_p ; s++)
  205.         {
  206.             if (!s->spans)
  207.                 continue;
  208.  
  209.             r_drawnpolycount++;
  210.  
  211.             d_zistepu = s->d_zistepu;
  212.             d_zistepv = s->d_zistepv;
  213.             d_ziorigin = s->d_ziorigin;
  214.  
  215.             if (s->flags & SURF_DRAWSKY)
  216.             {
  217.                 if (!r_skymade)
  218.                 {
  219.                     R_MakeSky ();
  220.                 }
  221.  
  222.                 D_DrawSkyScans8 (s->spans);
  223.                 D_DrawZSpans (s->spans);
  224.             }
  225.             else if (s->flags & SURF_DRAWBACKGROUND)
  226.             {
  227.             // set up a gradient for the background surface that places it
  228.             // effectively at infinity distance from the viewpoint
  229.                 d_zistepu = 0;
  230.                 d_zistepv = 0;
  231.                 d_ziorigin = -0.9;
  232.  
  233.                 D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
  234.                 D_DrawZSpans (s->spans);
  235.             }
  236.             else if (s->flags & SURF_DRAWTURB)
  237.             {
  238.                 pface = s->data;
  239.                 miplevel = 0;
  240.                 cacheblock = (pixel_t *)
  241.                         ((byte *)pface->texinfo->texture +
  242.                         pface->texinfo->texture->offsets[0]);
  243.                 cachewidth = 64;
  244.  
  245.                 if (s->insubmodel)
  246.                 {
  247.                 // FIXME: we don't want to do all this for every polygon!
  248.                 // TODO: store once at start of frame
  249.                     currententity = s->entity;    //FIXME: make this passed in to
  250.                                                 // R_RotateBmodel ()
  251.                     VectorSubtract (r_origin, currententity->origin,
  252.                             local_modelorg);
  253.                     TransformVector (local_modelorg, transformed_modelorg);
  254.  
  255.                     R_RotateBmodel ();    // FIXME: don't mess with the frustum,
  256.                                         // make entity passed in
  257.                 }
  258.  
  259.                 D_CalcGradients (pface);
  260.                 Turbulent8 (s->spans);
  261.                 D_DrawZSpans (s->spans);
  262.  
  263.                 if (s->insubmodel)
  264.                 {
  265.                 //
  266.                 // restore the old drawing state
  267.                 // FIXME: we don't want to do this every time!
  268.                 // TODO: speed up
  269.                 //
  270.                     currententity = &cl_entities[0];
  271.                     VectorCopy (world_transformed_modelorg,
  272.                                 transformed_modelorg);
  273.                     VectorCopy (base_vpn, vpn);
  274.                     VectorCopy (base_vup, vup);
  275.                     VectorCopy (base_vright, vright);
  276.                     VectorCopy (base_modelorg, modelorg);
  277.                     R_TransformFrustum ();
  278.                 }
  279.             }
  280.             else
  281.             {
  282.                 if (s->insubmodel)
  283.                 {
  284.                 // FIXME: we don't want to do all this for every polygon!
  285.                 // TODO: store once at start of frame
  286.                     currententity = s->entity;    //FIXME: make this passed in to
  287.                                                 // R_RotateBmodel ()
  288.                     VectorSubtract (r_origin, currententity->origin, local_modelorg);
  289.                     TransformVector (local_modelorg, transformed_modelorg);
  290.  
  291.                     R_RotateBmodel ();    // FIXME: don't mess with the frustum,
  292.                                         // make entity passed in
  293.                 }
  294.  
  295.                 pface = s->data;
  296.                 miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
  297.                 * pface->texinfo->mipadjust);
  298.  
  299.             // FIXME: make this passed in to D_CacheSurface
  300.                 pcurrentcache = D_CacheSurface (pface, miplevel);
  301.  
  302.                 cacheblock = (pixel_t *)pcurrentcache->data;
  303.                 cachewidth = pcurrentcache->width;
  304.  
  305.                 D_CalcGradients (pface);
  306.  
  307.                 (*d_drawspans) (s->spans);
  308.  
  309.                 D_DrawZSpans (s->spans);
  310.  
  311.                 if (s->insubmodel)
  312.                 {
  313.                 //
  314.                 // restore the old drawing state
  315.                 // FIXME: we don't want to do this every time!
  316.                 // TODO: speed up
  317.                 //
  318.                     currententity = &cl_entities[0];
  319.                     VectorCopy (world_transformed_modelorg,
  320.                                 transformed_modelorg);
  321.                     VectorCopy (base_vpn, vpn);
  322.                     VectorCopy (base_vup, vup);
  323.                     VectorCopy (base_vright, vright);
  324.                     VectorCopy (base_modelorg, modelorg);
  325.                     R_TransformFrustum ();
  326.                 }
  327.             }
  328.         }
  329.     }
  330. }
  331.  
  332.